// Classe Grafo.

#include <vcl.h>
#include <list>

#include "ClasseNoGrafo.h"
#include "ClasseGrafo.h"

//---------------------------------------------------------------------------
Grafo::Grafo()
{
  ListaGrafo.clear();
}

//---------------------------------------------------------------------------
bool Grafo::Empty()
{
  return (ListaGrafo.empty());
}

//---------------------------------------------------------------------------
void Grafo::InsereVertice(int indice, String texto)
{
  NoGrafo vertice(indice, texto);     // Cria um vertice do tipo NoGrafo.
  ListaGrafo.push_back(vertice);     // Adiciona ele no final da ListaGrafo.
}

//---------------------------------------------------------------------------
void Grafo::RemoveVertice(int indice)
{
  int tamanho, i, j;
  std::list<NoGrafo>::iterator percorre, busca;

  tamanho  = ListaGrafo.size();
  percorre = ListaGrafo.begin();

     // Percorre a lista de vertices verificando se o vertice existe.
  for(i= 1; i <= tamanho; i++)
    {
     if(percorre->getIndice() == indice)     // Encontrou o vertice.
       {
        if(! (percorre->ArestaEmpty()))     // Existe alguma aresta para o vertice.
          {
           busca = ListaGrafo.begin();

              // Percorre a lista eliminando os vinculos de arestas
              // existente nos demais vertices.
           for(j= 1; j <= tamanho; j++)
             {
              if(busca->getIndice() != indice)
                {
                 busca->delAresta(indice);     // Elimina aresta referente ao vertice.
                }
              ++busca;
             }
          }
        ListaGrafo.erase(percorre);     // Elimina o vertice solicitado.
        i = (tamanho + 1);
       }
     else
       {
        ++percorre;
       }
    }
}

//---------------------------------------------------------------------------
void Grafo::InsereAresta(int verticeA, int verticeB)
{
  int tamanho, i;
  std::list<NoGrafo>::iterator percorre;

     // So insere aresta se os vertices forem diferentes.
  if((verticeA != verticeB))
    {
     tamanho  = ListaGrafo.size();
     percorre = ListaGrafo.begin();

        // Percorre a lista de vertices encontrando os vertices.
     for(i= 1; i <= tamanho; i++)
       {
        if((percorre->getIndice() == verticeA))
          {
              // No vertice A cria vinculo com o vertice B.
           percorre->addAresta(verticeB);
          }
        if((percorre->getIndice() == verticeB))
          {
              // No vertice B cria vinculo com o vertice A.
           percorre->addAresta(verticeA);
          }
        ++percorre;
       }
    }
}

//---------------------------------------------------------------------------
void Grafo::RemoveAresta(int verticeA, int verticeB)
{
  int tamanho, i;
  std::list<NoGrafo>::iterator percorre;

     // So remove aresta se os vertices forem diferentes.
  if((verticeA != verticeB))
    {
     tamanho  = ListaGrafo.size();
     percorre = ListaGrafo.begin();

        // Percorre a lista de vertices encontrando os vertices.
     for(i= 1; i <= tamanho; i++)
       {
        if((percorre->getIndice() == verticeA))
          {
              // No vertice A remove vinculo com o vertice B.
           percorre->delAresta(verticeB);
          }
        if((percorre->getIndice() == verticeB))
          {
              // No vertice B remove vinculo com o vertice A.
           percorre->delAresta(verticeA);
          }
        ++percorre;
       }
    }
}

//---------------------------------------------------------------------------
int Grafo::QtdeVertice()
{
  return (ListaGrafo.size());
}

//---------------------------------------------------------------------------
int Grafo::QtdeAresta(int vertice)
{
  int tamanho, i, retorno;
  std::list<NoGrafo>::iterator percorre;

  tamanho  = ListaGrafo.size();
  percorre = ListaGrafo.begin();
  retorno  = 0;

     // Percorre a lista de vertices encontrando o vertice.
  for(i= 1; i <= tamanho; i++)
    {
     if((percorre->getIndice() == vertice))     // Achou o vertice.
       {
        retorno = (percorre->QtdeAresta());     // Pega a quantidade de arestas para retorno.
        i = (tamanho + 1);
       }
     else
       {
        ++percorre;
       }
    }

  return (retorno);
}

//---------------------------------------------------------------------------
String Grafo::getTexto(int vertice)
{
  int tamanho, i;
  String retorno;
  std::list<NoGrafo>::iterator percorre;

  tamanho  = ListaGrafo.size();
  percorre = ListaGrafo.begin();
  retorno  = "";

     // Percorre a lista de vertices encontrando o vertice.
  for(i= 1; i <= tamanho; i++)
    {
     if((percorre->getIndice() == vertice))     // Achou o vertice.
       {
        retorno = (percorre->getPalavra());     // Pega o texto do vertice para retorno.
        i = (tamanho + 1);
       }
     else
       {
        ++percorre;
       }
    }

  return (retorno);
}

//---------------------------------------------------------------------------
int Grafo::getAresta(int vertice, int posicao)
{
  int tamanho, i, retorno;
  std::list<NoGrafo>::iterator percorre;

  tamanho  = ListaGrafo.size();
  percorre = ListaGrafo.begin();
  retorno  = (-1);

     // Percorre a lista de vertices encontrando o vertice.
  for(i= 1; i <= tamanho; i++)
    {
     if((percorre->getIndice() == vertice))     // Achou o vertice.
       {
           // Pega o valor da aresta existente em posicao para retorno.
        retorno = (percorre->getAresta(posicao));
        i = (tamanho + 1);
       }
     else
       {
        ++percorre;
       }
    }

  return (retorno);
}

//---------------------------------------------------------------------------
void Grafo::LimpaGrafo()
{
  ListaGrafo.clear();
}

//---------------------------------------------------------------------------

